<?php
/***********************************************************************
 * @package     IvanEngine
 * @subpackage  Framework
 * @author      Ivan <ivanzx@msn.com>
 * @created     2010-05-23
 ***********************************************************************/
if(defined("IVANENGINE_FRAMEWORK_MVC_VIEW"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_FRAMEWORK_MVC_VIEW", true);

require_once (dirname(__FILE__).'/../Common.php');

class CView extends CObject 
{
    const RM_TEXT       = 'text';
    const RM_HTML       = 'html';
    const RM_APPEND     = 'append';
    
    protected 
        $m_content      = '',
        $m_script       = '',
        $m_winName      = null,
        $m_renderMode   = self::RM_HTML,
        $m_preContent   = '',
        $m_preScript    = '',
        $m_preWinName   = null,
        $m_preRenderMode= self::RM_HTML,
        $m_winMgr       = null;
    
	public function __construct($winName, $renderMode = self::RM_APPEND,
        $preWinName = CWindow::ROOT_NAME, $preRenderMode = self::RM_APPEND)
	{
		parent::__construct();
        $this->m_winMgr     = CWindowManager::Get();
        $this->m_renderMode = $renderMode;
        $this->m_preRenderMode = $preRenderMode;
        $this->SetWindow($winName);
        $this->SetWindow($preWinName, true);
	}

	public function __destruct()
	{
        unset($this->m_winName);
        unset($this->m_winMgr);
		parent::__destruct();
	}
    
    public function Clear()
    {
        $this->m_preContent = '';
        $this->m_preScript  = '';
        $this->m_content    = '';
        $this->m_script     = '';
    }
    
    public function AddContent($content, $previously = false)
    {
        if( $previously ){
            $this->m_preContent.= $content;
        }else{
            $this->m_content.= $content;
        }
    }
    
    public function SetContent($content, $previously = false)
    {
        if( $previously ){
            $this->m_preContent = $content;
        }else{
            $this->m_content = $content;
        }
    }
    
    public function GetContent($previously = false)
    {
        if( $previously ){
            return $this->m_preContent;
        }else{
            return $this->m_content;
        }
    }
    
    public function AddScript($content, $previously = false)
    {
        if( $previously ){
            $this->m_preScript .= $content.M_WARP;
        }else{
            $this->m_script .= $content.M_WARP;
        }
    }
    
    public function SetScript($content, $previously = false)
    {
        if( $previously ){
            $this->m_preScript = $content.M_WARP;
        }else{
            $this->m_script = $content.M_WARP;
        }
    }
    
    public function GetScript($previously = false)
    {
        if( $previously ){
            return $this->m_preScript;
        }else{
            return $this->m_script;
        }
    }
    
    public function SetWindow($winName, $previously = false)
    {
        if( !$this->m_winMgr->HasInStorage($winName) )
        {
            $failed = true;
            if( $winName == $this->m_winMgr->GetRoot()->GetName() || 
                (   $this->m_winMgr->HasWindow($winName) && 
                    $this->m_preWinName != $winName
                ) 
            )
            {
                $failed = false;
            }
            if( $failed ){
                throw new CExceptionInvalidArgument(
                    'can not find out the window instance: '.$winName);
            }
        }
            
        if( $previously ){
            $this->m_preWinName = $winName;
        }else{
            $this->m_winName    = $winName;
        }
    }
    
    public function GetWindow($previously = false)
    {
        if( $previously ){
            return $this->m_preWinName;
        }else{
            return $this->m_winName;
        }
    }
    
    public function SetRenderMode($renderMode, $previously = false)
    {
        if( $previously ){
            $this->m_preRenderMode = $renderMode;
        }else{
            $this->m_renderMode = $renderMode;
        }
    }
    
    public function GetRenderMode($previously = false)
    {
        if( $previously ){
            return $this->m_preRenderMode;
        }else{
            return $this->m_renderMode;
        }
    }
    
    protected function _ExtractScriptCode($content, $previously)
    {
        $result = CStringHelper::ExtractScriptCode($content);
        foreach( $result[1] as $script ){
            $this->AddScript($script, $previously);
        }
        return $result[0];
    }
    
    public function Render($previously = true, $aftermost = true)
    {
        $content    = '';
        if( $previously && $this->m_preWinName )
        {
            if( CRequest::Get()->IsXmlHttpRequest() )
            {
                if( !empty($this->m_preContent) ){
                    $tmpStr   = $this->_ExtractScriptCode($this->m_preContent, true);
                    $content .= $tmpStr.M_WARP;
                }
                if( !empty($this->m_preScript) ){
                    $content .= CTagHelper::ContentTag('script', 
                        M_WARP.$this->m_preScript);
                    $content .= M_WARP;
                }
                
                if( strlen($content) > 0 ){
                    $winID  = CWindow::ID($this->m_preWinName);
                    if( $this->m_preWinName == CWindow::ROOT_NAME ){
                        $winID= 'body';
                    }
                    $preWinTag = '<!--#PW#'.$winID.
                        '||'.$this->m_preRenderMode.'#PW#-->';
                    $content = $preWinTag.$content.$preWinTag.M_WARP;
                }
            }else{
                if( !empty($this->m_preContent) ){
                    $winID  = '\'#'.CWindow::ID($this->m_preWinName).'\'';
                    if( $this->m_preWinName == CWindow::ROOT_NAME ){
                        $winID= '\'body\'';
                    }
                    $content .= '$('.$winID.').';
                    $content .= $this->m_preRenderMode."('";
                    $tmpStr   = $this->_ExtractScriptCode($this->m_preContent, true);
                    $content .= CStringHelper::ToJS($tmpStr)."');".M_WARP;
                }
                if( !empty($this->m_preScript) ){
                    $content .= $this->m_preScript;
                }
            }
        }
        
        if( $aftermost && $this->m_winName )
        {
            if( CRequest::Get()->IsXmlHttpRequest() )
            {
                if( !empty($this->m_content) ){
                    $tmpStr   = $this->_ExtractScriptCode($this->m_content, false);
                    $content .= $tmpStr.M_WARP;
                }
                if( !empty($this->m_script) ){
                    $content .= CTagHelper::ContentTag('script', 
                        M_WARP.$this->m_script);
                    $content .= M_WARP;
                }
                
                if( strlen($content) > 0 ){
                    $winID  = CWindow::ID($this->m_winName);
                    if( $this->m_winName == CWindow::ROOT_NAME ){
                        $winID= 'body';
                    }
                    $winTag = '<!--#W#'.$winID.
                        '||'.$this->m_renderMode.'#W#-->';
                    $content = $winTag.$content.$winTag.M_WARP;
                }
            }else{
                if( !empty($this->m_content) ){
                    $winID  = '\'#'.CWindow::ID($this->m_winName).'\'';
                    if( $this->m_winName == CWindow::ROOT_NAME ){
                        $winID= '\'body\'';
                    }
                    $content .= '$('.$winID.').';
                    $content .= $this->m_renderMode."('";
                    $tmpStr   = $this->_ExtractScriptCode($this->m_content, false);
                    $content .= CStringHelper::ToJS($tmpStr)."');".M_WARP;
                }
                if( !empty($this->m_script) ){
                    $content .= $this->m_script;
                }
                if( !empty($content) ){
                    $content = CTagHelper::ContentTag('script', M_WARP.$content);
                }
            }
        }
        
        if( !empty($content) && strlen($content) > 1 )
        {
            CPrinter::Get()->GetRoot()->AddContent($content);
        }
        
        /*
        if( !empty($content) )
        {
            $array      = array();
            $getCodeReg = '#<script>(?>[^<]*)(?>(?!</?script>)<[^<]*)*</script>#is';
            $filterReg  = "/<(\/?script.*?)>/si";
            preg_match_all($getCodeReg, $content, $array);
            foreach( $array as $scripts ){
                if( is_array($scripts) ){
                    foreach( $scripts as $script ){
                        $script = preg_replace($filterReg, "", $script);
                        $this->AddScript(stripslashes($script));
                    }
                }else{
                    $scripts = preg_replace($filterReg,"", $scripts);
                    $this->AddScript($scripts);
                }
            }
            
            $content    = preg_replace($getCodeReg, '', $content);
        }
        */
    }
}
?>